/* Jason Luu
   June 26, 2013

   Carry chain arch generator.  Creates arch files of fracturable 6-LUTs with varying parameters.  Each fracturable 6-LUT can operate as one 6-LUT or two 5 LUTs with shared inputs.
   The number of pins in dual 5-LUT mode is labelled FI where an FI = 5 means all 5 pins of the dual 5-LUTs are shared and an FI = 10 means no pins are shared.
   Each 5-LUT can operate in arithmetic mode which consists of a one-bit full adder that is fed by two 4-lUTs with all 4 inputs shared.  The adder cout pin drives the cin pin of the adjacent adder directly below.

   FI varies from 5 to 10 and inputs to CLB (I) varies from 50 to 100

   To run, enter: ./gen_c_chain_arch_sweep

*/

#include <stdio.h>
#include <assert.h>


static void print_header(FILE *fpout);
static void print_clb(FILE *fpout, int FI, int clbI);
static void print_footer(FILE *fpout);

int main(void) {
	FILE *fpout;
	char fname[100]; /* Architecture file name */

	/* Create architectures sweeping through all FI from 5 to 10 and CLB inputs 50, 60, 70, 80, 90, 100 */
	for(int i_FI = 5; i_FI <= 10; i_FI++) {
		for(int i_clbI = 50; i_clbI <= 100; i_clbI += 10) {
			/* Open arch file for writing */
			sprintf(fname, "chain_FI%d_I%d.xml", i_FI, i_clbI);
			fpout = fopen(fname, "w");

			/* Populate arch file */
			print_header(fpout);
			print_clb(fpout, i_FI, i_clbI);
			print_footer(fpout);

			/* Close arch file */
			fclose(fpout);
		}
	}

	return 0;
}


static void print_header(FILE *fpout) {
	fprintf(fpout, "<!-- \n");
	fprintf(fpout, "  Flagship Heterogeneous Architecture with Carry Chains for VTR 7.0.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  - 40 nm technology\n");
	fprintf(fpout, "  - General purpose logic block: \n");
	fprintf(fpout, "    K = 6, N = 10, fracturable 6 LUTs (can operate as one 6-LUT or two 5-LUTs with all 5 inputs shared) \n");
	fprintf(fpout, "    with optionally registered outputs\n");
	fprintf(fpout, "    Each 5-LUT has an arithemtic mode that converts it to a single-bit adder with both inputs driven by 4-LUTs (both 4-LUTs share all 4 inputs)\n");
	fprintf(fpout, "    Carry chain links to vertically adjacent logic blocks\n");
	fprintf(fpout, "  - Memory size 32 Kbits, memory aspect ratios vary from a data width of 1 to data width of 64.  \n");
	fprintf(fpout, "    Height = 6, found on every (8n+2)th column\n");
	fprintf(fpout, "  - Multiplier modes: one 36x36, two 18x18, each 18x18 can also operate as two 9x9.  \n");
	fprintf(fpout, "    Height = 4, found on every (8n+6)th column\n");
	fprintf(fpout, "  - Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  Details on Modelling:\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  The electrical design of the architecture described here is NOT from an \n");
	fprintf(fpout, "  optimized, SPICED architecture.  Instead, we attempt to create a reasonable \n");
	fprintf(fpout, "  architecture file by using an existing commercial FPGA to approximate the area, \n");
	fprintf(fpout, "  delay, and power of the underlying components. This is combined with a reasonable 40 nm \n");
	fprintf(fpout, "  model of wiring and circuit design for low-level routing components, where available.\n");
	fprintf(fpout, "  The resulting architecture has delays that roughly match a commercial 40 nm FPGA, but also \n");
	fprintf(fpout, "  has wiring electrical parameters that allow the wire lengths and switch patterns to be \n");
	fprintf(fpout, "  modified and you will still get reasonable delay results for the new architecture.\n");
	fprintf(fpout, "  The following describes, in detail, how we obtained the various electrical values for this \n");
	fprintf(fpout, "  architecture.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  Rmin for nmos and pmos, routing buffer sizes, and I/O pad delays are from the ifar \n");
	fprintf(fpout, "  architecture created by Ian Kuon: K06 N10 45nm fc 0.15 area-delay optimized architecture. \n");
	fprintf(fpout, "  (n10k06l04.fc15.area1delay1.cmos45nm.bptm.cmos45nm.xml)      \n");
	fprintf(fpout, "  This routing architecture was optimized for 45 nm, and we have scaled it linearly to 40 nm to \n");
	fprintf(fpout, "  match the overall target (a 40 nm FPGA).\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  We obtain delay numbers by measuring delays of routing, soft logic blocks, \n");
	fprintf(fpout, "  memories, and multipliers from test circuits on a Stratix IV GX device \n");
	fprintf(fpout, "  (EP4SGX230DF29C2X, i.e. fastest speed grade). For routing, we took the average delay of H4 and V4 \n");
	fprintf(fpout, "  wires.  Rmetal and Cmetal values for the routing wires were obtained from work done by Charles \n");
	fprintf(fpout, "  Chiasson. We use a 96 nm half-pitch (corresponding to mid-level metal stack 40 nm routing) and \n");
	fprintf(fpout, "  take the R and C data from the ITRS roadmap.  \n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  For the general purpose logic block, we assume that the area and delays of the Stratix IV \n");
	fprintf(fpout, "  crossbar is close enough to the crossbar modelled here.  We use 33 inputs and 20 feedback lines in \n");
	fprintf(fpout, "  the cluster and a full crossbar, leading to 53:1 multiplexers in front of each BLE input.\n");
	fprintf(fpout, "  Stratix IV uses 52 inputs and 20 feedback lines, but only a half-populated crossbar, leading to \n");
	fprintf(fpout, "  36:1 multiplexers.  We require 60 such multiplexers, while Stratix IV requires 88 for its more\n");
	fprintf(fpout, "  complex fracturable BLEs + the extra control signals. We justify this rough approximation as follows: \n");
	fprintf(fpout, "  The Stratix IV crossbar has more inputs (72 vs. 53) and \n");
	fprintf(fpout, "  outputs (88 vs. 60) than our full crossbar which should increase its area and delay, but the \n");
	fprintf(fpout, "  Stratix IV crossbar is also 50%% sparse (each mux is 36:1 instead of 53:1) which should reduce its \n");
	fprintf(fpout, "  area and delay.  The total number of crossbar switch points is very similar between the two \n");
	fprintf(fpout, "  architectures (3160 for SIV and 3180 for the academic architecture below), so we can use the area \n");
	fprintf(fpout, "  & delay of the Stratix IV crossbar as a good approximation of our crossbar.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  For LUTs, we include LUT \n");
	fprintf(fpout, "  delays measured from Stratix IV which is dependant on the input used (ie. some \n");
	fprintf(fpout, "  LUT inputs are faster than others).  The CAD tools at the time of VTR 7 does \n");
	fprintf(fpout, "  not consider differences in LUT input delays.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  Adder delays obtained as approximate values from a Stratix IV EP4SE230F29C3 device.  \n");
	fprintf(fpout, "  Delay obtained by compiling a 256 bit adder (registered inputs and outputs, \n");
	fprintf(fpout, "  all pins except clock virtual) then measuring the delays in chip-planner, \n");
	fprintf(fpout, "  sumout delay = 0.271ns to 0.348 ns, intra-block carry delay = 0.011 ns, \n");
	fprintf(fpout, "  inter-block carry delay = 0.327 ns.  Given this data, I will approximate \n");
	fprintf(fpout, "  sumout 0.3 ns, intra-block carry-delay = 0.01 ns, and \n");
	fprintf(fpout, "  inter-block carry-delay = 0.16 ns (since Altera inter-block carry delay has \n");
	fprintf(fpout, "  overhead that we don't have, I'll approximate the delay of a simpler chain at \n");
	fprintf(fpout, "  one half what they have.  This is very rough, anything from 0.01ns to 0.327ns \n");
	fprintf(fpout, "  can be justified).\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  Logic block area numbers obtained by scaling overall tile area of a 65nm \n");
	fprintf(fpout, "  Stratix III device, (as given in Wong, Betz and Rose, FPGA 2011) to 40 nm, then subtracting out \n");
	fprintf(fpout, "  routing area at a channel width of 300. We use a channel width of 300 because it can route \n");
	fprintf(fpout, "  all the VTR 6.0 benchmark circuits with an approximately 20%% safety margin, and is also close to the\n");
	fprintf(fpout, "  total channel width of Stratix IV. Hence this channel width is close to the commercial practice of\n");
	fprintf(fpout, "  choosing a width that provides high routability. The architecture can be routed at different channel\n");
	fprintf(fpout, "  widths, but we estimate the tile size and hence the physical length of routing wires assuming\n");
	fprintf(fpout, "  a channel width of 300.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  Sanity checks employed:\n");
	fprintf(fpout, "    1.  We confirmed the routing buffer delay is ~1/3rd of total routing delay at L = 4. This matches \n");
	fprintf(fpout, "        common electrical design.\n");
	fprintf(fpout, "\n");

	fprintf(fpout, "  Authors: Jason Luu, Jeff Goeders, Vaughn Betz\n");
	fprintf(fpout, "-->\n");
	fprintf(fpout, "  \n");
	fprintf(fpout, "  \n");
	fprintf(fpout, "  <architecture>\n");
	fprintf(fpout, "  \n");
	fprintf(fpout, "  <!-- \n");
	fprintf(fpout, "       ODIN II specific config begins \n");
	fprintf(fpout, "       Describes the types of user-specified netlist blocks (in blif, this corresponds to \n");
	fprintf(fpout, "       \".model [type_of_block]\") that this architecture supports.\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "       Note: Basic LUTs, I/Os, and flip-flops are not included here as there are \n");
	fprintf(fpout, "       already special structures in blif (.names, .input, .output, and .latch) \n");
	fprintf(fpout, "       that describe them.\n");
	fprintf(fpout, "  -->\n");
	fprintf(fpout, "  <models>\n");
	fprintf(fpout, "    <model name=\"multiply\">\n");
	fprintf(fpout, "      <input_ports>\n");
	fprintf(fpout, "      <port name=\"a\"/>\n");
	fprintf(fpout, "      <port name=\"b\"/>\n");
	fprintf(fpout, "      </input_ports>\n");
	fprintf(fpout, "      <output_ports>\n");
	fprintf(fpout, "      <port name=\"out\"/>\n");
	fprintf(fpout, "      </output_ports>\n");
	fprintf(fpout, "    </model>\n");
	fprintf(fpout, "    \n");
	fprintf(fpout, "    <model name=\"single_port_ram\">\n");
	fprintf(fpout, "      <input_ports>\n");
	fprintf(fpout, "      <port name=\"we\"/>     <!-- control -->\n");
	fprintf(fpout, "      <port name=\"addr\"/>  <!-- address lines -->\n");
	fprintf(fpout, "      <port name=\"data\"/>  <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      <port name=\"clk\" is_clock=\"1\"/>  <!-- memories are often clocked -->\n");
	fprintf(fpout, "      </input_ports>\n");
	fprintf(fpout, "      <output_ports>\n");
	fprintf(fpout, "      <port name=\"out\"/>   <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      </output_ports>\n");
	fprintf(fpout, "    </model>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "    <model name=\"dual_port_ram\">\n");
	fprintf(fpout, "      <input_ports>\n");
	fprintf(fpout, "      <port name=\"we1\"/>     <!-- write enable -->\n");
	fprintf(fpout, "      <port name=\"we2\"/>     <!-- write enable -->\n");
	fprintf(fpout, "      <port name=\"addr1\"/>  <!-- address lines -->\n");
	fprintf(fpout, "      <port name=\"addr2\"/>  <!-- address lines -->\n");
	fprintf(fpout, "      <port name=\"data1\"/>  <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      <port name=\"data2\"/>  <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      <port name=\"clk\" is_clock=\"1\"/>  <!-- memories are often clocked -->\n");
	fprintf(fpout, "      </input_ports>\n");
	fprintf(fpout, "      <output_ports>\n");
	fprintf(fpout, "      <port name=\"out1\"/>   <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      <port name=\"out2\"/>   <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
	fprintf(fpout, "      </output_ports>\n");
	fprintf(fpout, "    </model>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "    <model name=\"adder\">\n");
	fprintf(fpout, "      <input_ports>\n");
	fprintf(fpout, "        <port name=\"a\"/>\n");
	fprintf(fpout, "        <port name=\"b\"/>\n");
	fprintf(fpout, "        <port name=\"cin\"/>\n");
	fprintf(fpout, "      </input_ports>\n");
	fprintf(fpout, "      <output_ports>\n");
	fprintf(fpout, "        <port name=\"cout\"/>\n");
	fprintf(fpout, "        <port name=\"sumout\"/>\n");
	fprintf(fpout, "      </output_ports>\n");
	fprintf(fpout, "    </model>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  </models>\n");
	fprintf(fpout, "  <!-- ODIN II specific config ends -->\n");
	fprintf(fpout, " \n");
	fprintf(fpout, "  <!-- Physical descriptions begin -->\n");
	fprintf(fpout, "  <layout auto=\"1.0\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "  		<device>\n");
	fprintf(fpout, "			<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM \n");
	fprintf(fpout, "			     models. We are modifying the delay values however, to include metal C and R, which allows more architecture\n");
	fprintf(fpout, "			     experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS\n");
	fprintf(fpout, "			     (vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of \n");
	fprintf(fpout, "			     45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping \n");
	fprintf(fpout, "			     RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately\n");
	fprintf(fpout, "			     lined up with Stratix IV. \n");
	fprintf(fpout, "			     We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).\n");
	fprintf(fpout, "			     Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).\n");
	fprintf(fpout, "			     The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file\n");
	fprintf(fpout, "	                     by 2.5x when looking up in Jeff's tables.\n");
	fprintf(fpout, "			     The delay values are lined up with Stratix IV, which has an architecture similar to this\n");
	fprintf(fpout, "			     proposed FPGA, and which is also 40 nm \n");
	fprintf(fpout, "			     C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage\n");
	fprintf(fpout, "			     4x minimum drive strength buffer. -->\n");
	fprintf(fpout, "   \n");
	fprintf(fpout, "    <sizing R_minW_nmos=\"8926\" R_minW_pmos=\"16067\" ipin_mux_trans_size=\"1.222260\"/>\n");
	fprintf(fpout, "    <timing C_ipin_cblock=\"1.47e-15\" T_ipin_cblock=\"7.247000e-11\"/>\n");
	fprintf(fpout, "      <!-- Total Stratix IV tile area is about 8100 um^2, minimum width transistor area is 60 L^2 yields a tile area of 84375 MWTAs,\n");
	fprintf(fpout, "	   Routing at W=300 is 30481 MWTAs, leaving us with a total of 53000 MWTAs for logic block area \n");
	fprintf(fpout, "	   This means that only 37%% of our area is in the general routing, and 63%% is inside the logic\n");
	fprintf(fpout, "	   block. Note that the crossbar / local interconnect is considered part of the logic block\n");
	fprintf(fpout, "	   area in this analysis. That is a lower proportion of of routing area than most academics\n");
	fprintf(fpout, "	   assume, but note that the total routing area really includes the crossbar, which would push\n");
	fprintf(fpout, "	   routing area up significantly, we estimate into the ~70%% range.\n");
	fprintf(fpout, "	   -->\n");
	fprintf(fpout, "			<area grid_logic_tile_area=\"53894\"/>\n");
	fprintf(fpout, "			<chan_width_distr>\n");
	fprintf(fpout, "				<io width=\"1.000000\"/>\n");
	fprintf(fpout, "				<x distr=\"uniform\" peak=\"1.000000\"/>\n");
	fprintf(fpout, "				<y distr=\"uniform\" peak=\"1.000000\"/>\n");
	fprintf(fpout, "			</chan_width_distr>\n");
	fprintf(fpout, "			<switch_block type=\"wilton\" fs=\"3\"/>\n");
	fprintf(fpout, "		</device>\n");
	fprintf(fpout, "		<switchlist>\n");
	fprintf(fpout, "      <!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple\n");
	fprintf(fpout, "           book area formula. This means the mux transistors are about 5x minimum drive strength.\n");
	fprintf(fpout, "           We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large \n");
	fprintf(fpout, "           mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume\n");
	fprintf(fpout, "           the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed\n");
	fprintf(fpout, "           by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified \n");
	fprintf(fpout, "           buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.\n");
	fprintf(fpout, "           I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout \n");
	fprintf(fpout, "           (diff of second stage) listed below.  Jeff's models are in tech/ptm_45nm, and are in min feature multiples.\n");
	fprintf(fpout, "           The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by \n");
	fprintf(fpout, "           2.5x when looking up in Jeff's tables.\n");
	fprintf(fpout, "           Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.\n");
	fprintf(fpout, "           This also leads to the switch being 46%% of the total wire delay, which is reasonable. -->\n");
	fprintf(fpout, "      <switch type=\"mux\" name=\"0\" R=\"551\" Cin=\".77e-15\" Cout=\"4e-15\" Tdel=\"58e-12\" mux_trans_size=\"2.630740\" buf_size=\"27.645901\"/>\n");
	fprintf(fpout, "		</switchlist>\n");
	fprintf(fpout, "		<segmentlist>\n");
	fprintf(fpout, "      <!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space.  \n");
	fprintf(fpout, "             With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems\n");
	fprintf(fpout, "             reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->\n");
	fprintf(fpout, "      <segment freq=\"1.000000\" length=\"4\" type=\"unidir\" Rmetal=\"101\" Cmetal=\"22.5e-15\">\n");
	fprintf(fpout, "        <mux name=\"0\"/>\n");
	fprintf(fpout, "        <sb type=\"pattern\">1 1 1 1 1</sb>\n");
	fprintf(fpout, "        <cb type=\"pattern\">1 1 1 1</cb>\n");
	fprintf(fpout, "			</segment>\n");
	fprintf(fpout, "		</segmentlist>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "    <directlist>\n");
	fprintf(fpout, "      <direct name=\"adder_carry\" from_pin=\"clb.cout\" to_pin=\"clb.cin\" x_offset=\"0\" y_offset=\"-1\" z_offset=\"0\"/>\n");
	fprintf(fpout, "    </directlist>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "		<complexblocklist>\n");
	fprintf(fpout, "      \n");
	fprintf(fpout, "      <!-- Define I/O pads begin -->\n");
	fprintf(fpout, "      <!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->\n");
	fprintf(fpout, "      <pb_type name=\"io\" capacity=\"8\">\n");
	fprintf(fpout, "        <input name=\"outpad\" num_pins=\"1\"/>\n");
	fprintf(fpout, "        <output name=\"inpad\" num_pins=\"1\"/>\n");
	fprintf(fpout, "        <clock name=\"clock\" num_pins=\"1\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "	<!-- IOs can operate as either inputs or outputs.\n");
	fprintf(fpout, "	     Delays below come from Ian Kuon. They are small, so they should be interpreted as\n");
	fprintf(fpout, "	     the delays to and from registers in the I/O (and generally I/Os are registered \n");
	fprintf(fpout, "	     today and that is when you timing analyze them.\n");
	fprintf(fpout, "	     -->\n");
	fprintf(fpout, "        <mode name=\"inpad\">\n");
	fprintf(fpout, "          <pb_type name=\"inpad\" blif_model=\".input\" num_pb=\"1\">\n");
	fprintf(fpout, "            <output name=\"inpad\" num_pins=\"1\"/>\n");
	fprintf(fpout, "          </pb_type>\n");
	fprintf(fpout, "          <interconnect>\n");
	fprintf(fpout, "            <direct name=\"inpad\" input=\"inpad.inpad\" output=\"io.inpad\">\n");
	fprintf(fpout, "            <delay_constant max=\"4.243e-11\" in_port=\"inpad.inpad\" out_port=\"io.inpad\"/>\n");
	fprintf(fpout, "            </direct>\n");
	fprintf(fpout, "          </interconnect>\n");
	fprintf(fpout, "      \n");
	fprintf(fpout, "        </mode>\n");
	fprintf(fpout, "        <mode name=\"outpad\">\n");
	fprintf(fpout, "          <pb_type name=\"outpad\" blif_model=\".output\" num_pb=\"1\">\n");
	fprintf(fpout, "            <input name=\"outpad\" num_pins=\"1\"/>\n");
	fprintf(fpout, "          </pb_type>\n");
	fprintf(fpout, "          <interconnect>\n");
	fprintf(fpout, "            <direct name=\"outpad\" input=\"io.outpad\" output=\"outpad.outpad\">\n");
	fprintf(fpout, "            <delay_constant max=\"1.394e-11\" in_port=\"io.outpad\" out_port=\"outpad.outpad\"/>\n");
	fprintf(fpout, "            </direct>\n");
	fprintf(fpout, "          </interconnect>\n");
	fprintf(fpout, "        </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "        <!-- Every input pin is driven by 15%% of the tracks in a channel, every output pin is driven by 10%% of the tracks in a channel -->\n");
	fprintf(fpout, "        <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "        <!-- IOs go on the periphery of the FPGA, for consistency, \n");
	fprintf(fpout, "          make it physically equivalent on all sides so that only one definition of I/Os is needed.\n");
	fprintf(fpout, "          If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA\n");
	fprintf(fpout, "        -->\n");
	fprintf(fpout, "        <pinlocations pattern=\"custom\">\n");
	fprintf(fpout, "          <loc side=\"left\">io.outpad io.inpad io.clock</loc>\n");
	fprintf(fpout, "          <loc side=\"top\">io.outpad io.inpad io.clock</loc>\n");
	fprintf(fpout, "          <loc side=\"right\">io.outpad io.inpad io.clock</loc>\n");
	fprintf(fpout, "          <loc side=\"bottom\">io.outpad io.inpad io.clock</loc>\n");
	fprintf(fpout, "        </pinlocations>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "        <!-- Place I/Os on the sides of the FPGA -->\n");
	fprintf(fpout, "        <gridlocations>\n");
	fprintf(fpout, "          <loc type=\"perimeter\" priority=\"10\"/>\n");
	fprintf(fpout, "        </gridlocations>\n");
	fprintf(fpout, "        <power method=\"ignore\"/>\n");
	fprintf(fpout, "      </pb_type>\n");
	fprintf(fpout, "      <!-- Define I/O pads ends -->\n");
	fprintf(fpout, "\n");
}

static void print_clb(FILE *fpout, int FI, int clbI) {
	assert(FI >= 5 && FI <= 10);
	fprintf(fpout, "      <!-- Define general purpose logic block (CLB) begin -->\n");
	fprintf(fpout, "      <pb_type name=\"clb\">\n");
	fprintf(fpout, "        <input name=\"I\" num_pins=\"%d\" equivalent=\"true\"/>\n", clbI);
	fprintf(fpout, "        <input name=\"cin\" num_pins=\"1\"/>\n");
	fprintf(fpout, "        <output name=\"O\" num_pins=\"20\" equivalent=\"false\"/>\n");
	fprintf(fpout, "        <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "        <clock name=\"clk\" num_pins=\"1\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "        <!-- Describe basic logic element with ifar delay numbers -->\n");
	fprintf(fpout, "        <pb_type name=\"fle\" num_pb=\"10\">\n");

	if(FI == 5) {
		fprintf(fpout, "          <input name=\"in\" num_pins=\"6\"/>\n");
	} else {
		fprintf(fpout, "          <input name=\"in\" num_pins=\"%d\"/>\n", FI);
	}

	fprintf(fpout, "          <input name=\"cin\" num_pins=\"1\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"2\"/>\n");
	fprintf(fpout, "          <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <mode name=\"n2_lut5\">\n");
	fprintf(fpout, "            <pb_type name=\"lut5inter\" num_pb=\"1\">\n");
	fprintf(fpout, "              <input name=\"in\" num_pins=\"%d\"/>\n", FI);
	fprintf(fpout, "              <input name=\"cin\" num_pins=\"1\"/>\n");
	fprintf(fpout, "              <output name=\"out\" num_pins=\"2\"/>\n");
	fprintf(fpout, "              <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "              <clock name=\"clk\" num_pins=\"1\"/>\n");
	fprintf(fpout, "              <pb_type name=\"ble5\" num_pb=\"2\">\n");
	fprintf(fpout, "                <input name=\"in\" num_pins=\"5\"/>\n");
	fprintf(fpout, "                <input name=\"cin\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                <output name=\"out\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                <clock name=\"clk\" num_pins=\"1\"/> \n");
	fprintf(fpout, "                <mode name=\"blut5\">\n");
	fprintf(fpout, "                  <pb_type name=\"flut5\" num_pb=\"1\">\n");
	fprintf(fpout, "                    <input name=\"in\" num_pins=\"5\"/>\n");
	fprintf(fpout, "                    <output name=\"out\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                    <clock name=\"clk\" num_pins=\"1\"/> \n");
	fprintf(fpout, "                    <!-- Regular LUT mode -->\n");
	fprintf(fpout, "                    <pb_type name=\"lut5\" blif_model=\".names\" num_pb=\"1\" class=\"lut\">\n");
	fprintf(fpout, "                      <input name=\"in\" num_pins=\"5\" port_class=\"lut_in\"/>\n");
	fprintf(fpout, "                      <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
	fprintf(fpout, "                      <!-- LUT timing using delay matrix -->\n");
	fprintf(fpout, "                        <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
	fprintf(fpout, "                           we instead take the average of these numbers to get more stable results\n");
	fprintf(fpout, "                        82e-12\n");
	fprintf(fpout, "                        173e-12\n");
	fprintf(fpout, "                        261e-12\n");
	fprintf(fpout, "                        263e-12\n");
	fprintf(fpout, "                        398e-12\n");
	fprintf(fpout, "                        -->\n");
	fprintf(fpout, "                      <delay_matrix type=\"max\" in_port=\"lut5.in\" out_port=\"lut5.out\">\n");
	fprintf(fpout, "                        235e-12\n");
	fprintf(fpout, "                        235e-12\n");
	fprintf(fpout, "                        235e-12\n");
	fprintf(fpout, "                        235e-12\n");
	fprintf(fpout, "                        235e-12\n");
	fprintf(fpout, "                      </delay_matrix>\n");
	fprintf(fpout, "                    </pb_type>       \n");
	fprintf(fpout, "                    \n");
	fprintf(fpout, "                    <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
	fprintf(fpout, "                      <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
	fprintf(fpout, "                      <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
	fprintf(fpout, "                      <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "                      <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
	fprintf(fpout, "                      <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
	fprintf(fpout, "                    </pb_type>\n");
	fprintf(fpout, "\n");

	fprintf(fpout, "                    <interconnect>\n");
	fprintf(fpout, "                      <direct name=\"direct1\" input=\"flut5.in\" output=\"lut5.in\"/>\n");
	fprintf(fpout, "                      <direct name=\"direct2\" input=\"lut5.out\" output=\"ff.D\">\n");
	fprintf(fpout, "                        <pack_pattern name=\"ble5\" in_port=\"lut5.out\" out_port=\"ff.D\"/>\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <direct name=\"direct3\" input=\"flut5.clk\" output=\"ff.clk\"/>                    \n");
	fprintf(fpout, "                      <mux name=\"mux1\" input=\"ff.Q lut5.out\" output=\"flut5.out\">\n");
	fprintf(fpout, "                        <delay_constant max=\"25e-12\" in_port=\"lut5.out\" out_port=\"flut5.out\" />\n");
	fprintf(fpout, "                        <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"flut5.out\" />\n");
	fprintf(fpout, "                      </mux>\n");
	fprintf(fpout, "                    </interconnect>\n");
	fprintf(fpout, "                  </pb_type>\n");
	fprintf(fpout, "                  <interconnect>\n");
	fprintf(fpout, "                    <direct name=\"direct1\" input=\"ble5.in\" output=\"flut5.in\"/>\n");
	fprintf(fpout, "                    <direct name=\"direct2\" input=\"ble5.clk\" output=\"flut5.clk\"/>\n");
	fprintf(fpout, "                    <direct name=\"direct3\" input=\"flut5.out\" output=\"ble5.out\"/>                                          \n");
	fprintf(fpout, "                  </interconnect>\n");
	fprintf(fpout, "                </mode>\n");
	fprintf(fpout, "                <mode name=\"arithmetic\">\n");
	fprintf(fpout, "                  <pb_type name=\"arithmetic\" num_pb=\"1\">\n");
	fprintf(fpout, "                    <input name=\"in\" num_pins=\"4\"/>\n");
	fprintf(fpout, "                    <input name=\"cin\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                    <output name=\"out\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                    <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                    <clock name=\"clk\" num_pins=\"1\"/> \n");
	fprintf(fpout, "                    <!-- Special dual-LUT mode that drives adder only -->\n");
	fprintf(fpout, "                    <pb_type name=\"lut4\" blif_model=\".names\" num_pb=\"2\" class=\"lut\">\n");
	fprintf(fpout, "                      <input name=\"in\" num_pins=\"4\" port_class=\"lut_in\"/>\n");
	fprintf(fpout, "                      <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
	fprintf(fpout, "                      <!-- LUT timing using delay matrix -->\n");
	fprintf(fpout, "                      <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
	fprintf(fpout, "                             we instead take the average of these numbers to get more stable results\n");
	fprintf(fpout, "                        82e-12\n");
	fprintf(fpout, "                        173e-12\n");
	fprintf(fpout, "                        261e-12\n");
	fprintf(fpout, "                        263e-12\n");
	fprintf(fpout, "                        -->\n");
	fprintf(fpout, "                      <delay_matrix type=\"max\" in_port=\"lut4.in\" out_port=\"lut4.out\">\n");
	fprintf(fpout, "                        195e-12\n");
	fprintf(fpout, "                        195e-12\n");
	fprintf(fpout, "                        195e-12\n");
	fprintf(fpout, "                        195e-12\n");
	fprintf(fpout, "                      </delay_matrix>\n");
	fprintf(fpout, "                    </pb_type>    \n");
	fprintf(fpout, "                    <pb_type name=\"adder\" blif_model=\".subckt adder\" num_pb=\"1\">\n");
	fprintf(fpout, "                      <input name=\"a\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                      <input name=\"b\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                      <input name=\"cin\" num_pins=\"1\"/>                      \n");
	fprintf(fpout, "                      <output name=\"cout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                      <output name=\"sumout\" num_pins=\"1\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.3e-9\" in_port=\"adder.a\" out_port=\"adder.sumout\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.3e-9\" in_port=\"adder.b\" out_port=\"adder.sumout\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.3e-9\" in_port=\"adder.cin\" out_port=\"adder.sumout\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.3e-9\" in_port=\"adder.a\" out_port=\"adder.cout\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.3e-9\" in_port=\"adder.b\" out_port=\"adder.cout\"/>\n");
	fprintf(fpout, "                      <delay_constant max=\"0.01e-9\" in_port=\"adder.cin\" out_port=\"adder.cout\"/>\n");
	fprintf(fpout, "                    </pb_type>\n");
	fprintf(fpout, "                    <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
	fprintf(fpout, "                      <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
	fprintf(fpout, "                      <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
	fprintf(fpout, "                      <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "                      <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
	fprintf(fpout, "                      <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
	fprintf(fpout, "                    </pb_type>\n");
	fprintf(fpout, "                    <interconnect>\n");
	fprintf(fpout, "                      <direct name=\"clock\" input=\"arithmetic.clk\" output=\"ff.clk\"/>\n");
	fprintf(fpout, "                      <direct name=\"lut_in1\" input=\"arithmetic.in[3:0]\" output=\"lut4[0:0].in[3:0]\"/>\n");
	fprintf(fpout, "                      <direct name=\"lut_in2\" input=\"arithmetic.in[3:0]\" output=\"lut4[1:1].in[3:0]\"/>\n");
	fprintf(fpout, "                      <direct name=\"lut_to_add1\" input=\"lut4[0:0].out\" output=\"adder.a\">\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <direct name=\"lut_to_add2\" input=\"lut4[1:1].out\" output=\"adder.b\">\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <direct name=\"add_to_ff\" input=\"adder.sumout\" output=\"ff.D\">\n");
	fprintf(fpout, "                        <pack_pattern name=\"chain\" in_port=\"adder.sumout\" out_port=\"ff.D\"/>\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <direct name=\"carry_in\" input=\"arithmetic.cin\" output=\"adder.cin\">\n");
	fprintf(fpout, "                        <pack_pattern name=\"chain\" in_port=\"arithmetic.cin\" out_port=\"adder.cin\"/>\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <direct name=\"carry_out\" input=\"adder.cout\" output=\"arithmetic.cout\">\n");
	fprintf(fpout, "                        <pack_pattern name=\"chain\" in_port=\"adder.cout\" out_port=\"arithmetic.cout\"/>\n");
	fprintf(fpout, "                      </direct>\n");
	fprintf(fpout, "                      <mux name=\"sumout\" input=\"ff.Q adder.sumout\" output=\"arithmetic.out\">\n");
	fprintf(fpout, "                        <delay_constant max=\"25e-12\" in_port=\"adder.sumout\" out_port=\"arithmetic.out\" />\n");
	fprintf(fpout, "                        <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"arithmetic.out\" />\n");
	fprintf(fpout, "                      </mux>\n");
	fprintf(fpout, "                    </interconnect>\n");
	fprintf(fpout, "                  </pb_type>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "                  <interconnect>\n");
	fprintf(fpout, "                    <direct name=\"direct1\" input=\"ble5.in[3:0]\" output=\"arithmetic.in\"/>\n");
	fprintf(fpout, "                    <direct name=\"carry_in\" input=\"ble5.cin\" output=\"arithmetic.cin\">\n");
	fprintf(fpout, "                      <pack_pattern name=\"chain\" in_port=\"ble5.cin\" out_port=\"arithmetic.cin\"/>\n");
	fprintf(fpout, "                    </direct>\n");
	fprintf(fpout, "                    <direct name=\"carry_out\" input=\"arithmetic.cout\" output=\"ble5.cout\">\n");
	fprintf(fpout, "                      <pack_pattern name=\"chain\" in_port=\"arithmetic.cout\" out_port=\"ble5.cout\"/>\n");
	fprintf(fpout, "                    </direct>\n");
	fprintf(fpout, "                    <direct name=\"direct2\" input=\"ble5.clk\" output=\"arithmetic.clk\"/>\n");
	fprintf(fpout, "                    <direct name=\"direct3\" input=\"arithmetic.out\" output=\"ble5.out\"/> \n");
	fprintf(fpout, "                  </interconnect>\n");
	fprintf(fpout, "                </mode>\n");
	fprintf(fpout, "              </pb_type>\n");
	fprintf(fpout, "              <interconnect>\n");
	fprintf(fpout, "                <direct name=\"direct1\" input=\"lut5inter.in[4:0]\" output=\"ble5[0:0].in\"/>\n");
	fprintf(fpout, "                <direct name=\"direct2\" input=\"lut5inter.in[%d:%d]\" output=\"ble5[1:1].in\"/>\n", FI - 1, FI - 5);
	fprintf(fpout, "                <direct name=\"direct3\" input=\"ble5[1:0].out\" output=\"lut5inter.out\"/>                 \n");
	fprintf(fpout, "                <direct name=\"carry_in\" input=\"lut5inter.cin\" output=\"ble5[0:0].cin\">\n");
	fprintf(fpout, "                  <pack_pattern name=\"chain\" in_port=\"lut5inter.cin\" out_port=\"ble5[0:0].cin\"/>\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"carry_out\" input=\"ble5[1:1].cout\" output=\"lut5inter.cout\">\n");
	fprintf(fpout, "                  <pack_pattern name=\"chain\" in_port=\"ble5[1:1].cout\" out_port=\"lut5inter.cout\"/>\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"carry_link\" input=\"ble5[0:0].cout\" output=\"ble5[1:1].cin\">\n");
	fprintf(fpout, "                  <pack_pattern name=\"chain\" in_port=\"ble5[0:0].cout\" out_port=\"ble5[1:1].cout\"/>\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <complete name=\"complete1\" input=\"lut5inter.clk\" output=\"ble5[1:0].clk\"/>                  \n");
	fprintf(fpout, "              </interconnect>\n");
	fprintf(fpout, "            </pb_type>\n");
	fprintf(fpout, "            <interconnect>\n");
	fprintf(fpout, "              <direct name=\"direct1\" input=\"fle.in[%d:0]\" output=\"lut5inter.in\"/>\n", FI - 1);
	fprintf(fpout, "              <direct name=\"direct2\" input=\"lut5inter.out\" output=\"fle.out\"/>\n");
	fprintf(fpout, "              <direct name=\"direct3\" input=\"fle.clk\" output=\"lut5inter.clk\"/>\n");
	fprintf(fpout, "              <direct name=\"carry_in\" input=\"fle.cin\" output=\"lut5inter.cin\">\n");
	fprintf(fpout, "                <pack_pattern name=\"chain\" in_port=\"fle.cin\" out_port=\"lut5inter.cin\"/>\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "              <direct name=\"carry_out\" input=\"lut5inter.cout\" output=\"fle.cout\">\n");
	fprintf(fpout, "                <pack_pattern name=\"chain\" in_port=\"lut5inter.cout\" out_port=\"fle.cout\"/>\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "            </interconnect>\n");
	fprintf(fpout, "          </mode> <!-- n2_lut5 -->\n");
	fprintf(fpout, "          <mode name=\"n1_lut6\">\n");
	fprintf(fpout, "            <pb_type name=\"ble6\" num_pb=\"1\">\n");
	fprintf(fpout, "              <input name=\"in\" num_pins=\"6\"/>\n");
	fprintf(fpout, "              <output name=\"out\" num_pins=\"1\"/>\n");
	fprintf(fpout, "              <clock name=\"clk\" num_pins=\"1\"/> \n");
	fprintf(fpout, "              <pb_type name=\"lut6\" blif_model=\".names\" num_pb=\"1\" class=\"lut\">\n");
	fprintf(fpout, "                <input name=\"in\" num_pins=\"6\" port_class=\"lut_in\"/>\n");
	fprintf(fpout, "                <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
	fprintf(fpout, "                <!-- LUT timing using delay matrix -->\n");
	fprintf(fpout, "                <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
	fprintf(fpout, "                       we instead take the average of these numbers to get more stable results\n");
	fprintf(fpout, "                  82e-12\n");
	fprintf(fpout, "                  173e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  263e-12\n");
	fprintf(fpout, "                  398e-12\n");
	fprintf(fpout, "                  397e-12\n");
	fprintf(fpout, "                  -->\n");
	fprintf(fpout, "                <delay_matrix type=\"max\" in_port=\"lut6.in\" out_port=\"lut6.out\">\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                  261e-12\n");
	fprintf(fpout, "                </delay_matrix>\n");
	fprintf(fpout, "              </pb_type>\n");
	fprintf(fpout, "              <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
	fprintf(fpout, "                <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
	fprintf(fpout, "                <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
	fprintf(fpout, "                <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "                <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
	fprintf(fpout, "                <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
	fprintf(fpout, "              </pb_type>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "              <interconnect>\n");
	fprintf(fpout, "                <direct name=\"direct1\" input=\"ble6.in\" output=\"lut6[0:0].in\"/>\n");
	fprintf(fpout, "                <direct name=\"direct2\" input=\"lut6.out\" output=\"ff.D\">\n");
	fprintf(fpout, "                  <pack_pattern name=\"ble6\" in_port=\"lut6.out\" out_port=\"ff.D\"/>\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"direct3\" input=\"ble6.clk\" output=\"ff.clk\"/>                    \n");
	fprintf(fpout, "                <mux name=\"mux1\" input=\"ff.Q lut6.out\" output=\"ble6.out\">\n");
	fprintf(fpout, "                  <delay_constant max=\"25e-12\" in_port=\"lut6.out\" out_port=\"ble6.out\" />\n");
	fprintf(fpout, "                  <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"ble6.out\" />\n");
	fprintf(fpout, "                </mux>\n");
	fprintf(fpout, "              </interconnect>\n");
	fprintf(fpout, "            </pb_type>\n");
	fprintf(fpout, "            <interconnect>\n");
	fprintf(fpout, "              <direct name=\"direct1\" input=\"fle.in[5:0]\" output=\"ble6.in\"/>\n");
	fprintf(fpout, "              <direct name=\"direct2\" input=\"ble6.out\" output=\"fle.out[0:0]\"/>\n");
	fprintf(fpout, "              <direct name=\"direct3\" input=\"fle.clk\" output=\"ble6.clk\"/>\n");
	fprintf(fpout, "            </interconnect>\n");
	fprintf(fpout, "          </mode> <!-- n1_lut6 -->\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <!-- We use a full crossbar to get logical equivalence at inputs of CLB \n");
	fprintf(fpout, "           The delays below come from Stratix IV. the delay through a connection block\n");
	fprintf(fpout, "           input mux + the crossbar in Stratix IV is 167 ps. We already have a 72 ps \n");
	fprintf(fpout, "           delay on the connection block input mux (modeled by Ian Kuon), so the remaining\n");
	fprintf(fpout, "           delay within the crossbar is 95 ps. \n");
	fprintf(fpout, "           The delays of cluster feedbacks in Stratix IV is 100 ps, when driven by a LUT.\n");
	fprintf(fpout, "           Since all our outputs LUT outputs go to a BLE output, and have a delay of \n");
	fprintf(fpout, "           25 ps to do so, we subtract 25 ps from the 100 ps delay of a feedback\n");
	fprintf(fpout, "           to get the part that should be marked on the crossbar.	 -->\n");
	fprintf(fpout, "          <complete name=\"crossbar\" input=\"clb.I fle[9:0].out\" output=\"fle[9:0].in\">\n");
	fprintf(fpout, "            <delay_constant max=\"95e-12\" in_port=\"clb.I\" out_port=\"fle[9:0].in\" />\n");
	fprintf(fpout, "            <delay_constant max=\"75e-12\" in_port=\"fle[9:0].out\" out_port=\"fle[9:0].in\" />\n");
	fprintf(fpout, "          </complete>\n");
	fprintf(fpout, "          <complete name=\"clks\" input=\"clb.clk\" output=\"fle[9:0].clk\">\n");
	fprintf(fpout, "          </complete>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.  \n");
	fprintf(fpout, "                 By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs, \n");
	fprintf(fpout, "                 then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more\n");
	fprintf(fpout, "                 naive specification).\n");
	fprintf(fpout, "          -->\n");
	fprintf(fpout, "          <direct name=\"clbouts1\" input=\"fle[9:0].out[0:0]\" output=\"clb.O[9:0]\"/>\n");
	fprintf(fpout, "          <direct name=\"clbouts2\" input=\"fle[9:0].out[1:1]\" output=\"clb.O[19:10]\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <!-- Carry chain links -->\n");
	fprintf(fpout, "          <direct name=\"carry_in\" input=\"clb.cin\" output=\"fle[0:0].cin\">\n");
	fprintf(fpout, "            <!-- Put all inter-block carry chain delay on this one edge -->\n");
	fprintf(fpout, "            <delay_constant max=\"0.16e-9\" in_port=\"clb.cin\" out_port=\"fle[0:0].cin\"/>\n");
	fprintf(fpout, "            <pack_pattern name=\"chain\" in_port=\"clb.cin\" out_port=\"fle[0:0].cin\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"carry_out\" input=\"fle[9:9].cout\" output=\"clb.cout\">\n");
	fprintf(fpout, "            <pack_pattern name=\"chain\" in_port=\"fle[9:9].cout\" out_port=\"clb.cout\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"carry_link\" input=\"fle[8:0].cout\" output=\"fle[9:1].cin\">\n");
	fprintf(fpout, "            <pack_pattern name=\"chain\" in_port=\"fle[8:0].cout\" out_port=\"fle[9:1].cin\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "\n");

	fprintf(fpout, "        <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\">\n");
	fprintf(fpout, "          <pin name=\"cin\" fc_type=\"frac\" fc_val=\"0\"/>\n");
	fprintf(fpout, "          <pin name=\"cout\" fc_type=\"frac\" fc_val=\"0\"/>\n");
	fprintf(fpout, "        </fc>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "        <pinlocations pattern=\"spread\"/>\n");
	fprintf(fpout, "        <gridlocations>\n");
	fprintf(fpout, "          <loc type=\"fill\" priority=\"1\"/>\n");
	fprintf(fpout, "        </gridlocations>\n");
	fprintf(fpout, "      </pb_type>\n");
	fprintf(fpout, "       <!-- Define general purpose logic block (CLB) ends -->\n");
	fprintf(fpout, "\n");
}

static void print_footer(FILE *fpout) {
	fprintf(fpout, "    <!-- Define fracturable multiplier begin -->\n");
	fprintf(fpout, "    <!-- This multiplier can operate as a 36x36 multiplier that can fracture to two 18x18 multipliers each of which can further fracture to two 9x9 multipliers \n");
	fprintf(fpout, "	   For delay modelling, the 36x36 DSP multiplier in Stratix IV has a delay of 1.523 ns + 1.93 ns\n");
	fprintf(fpout, "	    = 3.45 ns. The 18x18 mode doesn't need to sum four 18x18 multipliers, so it is a bit\n");
	fprintf(fpout, "	   faster: 1.523 ns for the multiplier, and 1.09 ns for the multiplier output block.\n");
	fprintf(fpout, "	    For the input and output interconnect delays, unlike Stratix IV, we don't\n");
	fprintf(fpout, "	   have any routing/logic flexibility (crossbars) at the inputs.  There is some output muxing\n");
	fprintf(fpout, "	   in Stratix IV and this architecture to select which multiplier outputs should go out (e.g.\n");
	fprintf(fpout, "	   9x9 outputs, 18x18 or 36x36) so those are very close between the two architectures. \n");
	fprintf(fpout, "	   We take the conservative (slightly pessimistic)\n");
	fprintf(fpout, "           approach modelling the input as the same as the Stratix IV input delay and the output delay the same as the Stratix IV DSP out delay.\n");
	fprintf(fpout, "      -->\n");
	fprintf(fpout, "    <pb_type name=\"mult_36\" height=\"4\">\n");
	fprintf(fpout, "      <input name=\"a\" num_pins=\"36\"/>\n");
	fprintf(fpout, "      <input name=\"b\" num_pins=\"36\"/>\n");
	fprintf(fpout, "      <output name=\"out\" num_pins=\"72\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"two_divisible_mult_18x18\">\n");
	fprintf(fpout, "        <pb_type name=\"divisible_mult_18x18\" num_pb=\"2\">\n");
	fprintf(fpout, "          <input name=\"a\" num_pins=\"18\"/>\n");
	fprintf(fpout, "          <input name=\"b\" num_pins=\"18\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"36\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <!-- Model 9x9 delay and 18x18 delay as the same.  9x9 could be faster, but in Stratix IV\n");
	fprintf(fpout, "	          isn't, presumably because the multiplier layout is really optimized for 18x18.\n");
	fprintf(fpout, "		-->\n");
	fprintf(fpout, "          <mode name=\"two_mult_9x9\">\n");
	fprintf(fpout, "            <pb_type name=\"mult_9x9_slice\" num_pb=\"2\">\n");
	fprintf(fpout, "              <input name=\"A_cfg\" num_pins=\"9\"/>\n");
	fprintf(fpout, "              <input name=\"B_cfg\" num_pins=\"9\"/>\n");
	fprintf(fpout, "              <output name=\"OUT_cfg\" num_pins=\"18\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "              <pb_type name=\"mult_9x9\" blif_model=\".subckt multiply\" num_pb=\"1\">\n");
	fprintf(fpout, "                <input name=\"a\" num_pins=\"9\"/>\n");
	fprintf(fpout, "                <input name=\"b\" num_pins=\"9\"/>\n");
	fprintf(fpout, "                <output name=\"out\" num_pins=\"18\"/>\n");
	fprintf(fpout, "                <delay_constant max=\"1.523e-9\" in_port=\"mult_9x9.a\" out_port=\"mult_9x9.out\"/>\n");
	fprintf(fpout, "                <delay_constant max=\"1.523e-9\" in_port=\"mult_9x9.b\" out_port=\"mult_9x9.out\"/>\n");
	fprintf(fpout, "              </pb_type>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "              <interconnect>\n");
	fprintf(fpout, "                <direct name=\"a2a\" input=\"mult_9x9_slice.A_cfg\" output=\"mult_9x9.a\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"b2b\" input=\"mult_9x9_slice.B_cfg\" output=\"mult_9x9.b\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"out2out\" input=\"mult_9x9.out\" output=\"mult_9x9_slice.OUT_cfg\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "              </interconnect>\n");
	fprintf(fpout, "              <power method=\"pin-toggle\">\n");
	fprintf(fpout, "                <port name=\"A_cfg\" energy_per_toggle=\"1.45e-12\"/>\n");
	fprintf(fpout, "                <port name=\"B_cfg\" energy_per_toggle=\"1.45e-12\"/>\n");
	fprintf(fpout, "                <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "              </power>\n");
	fprintf(fpout, "            </pb_type>\n");
	fprintf(fpout, "            <interconnect>\n");
	fprintf(fpout, "              <direct name=\"a2a\" input=\"divisible_mult_18x18.a\" output=\"mult_9x9_slice[1:0].A_cfg\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "              <direct name=\"b2b\" input=\"divisible_mult_18x18.b\" output=\"mult_9x9_slice[1:0].B_cfg\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "              <direct name=\"out2out\" input=\"mult_9x9_slice[1:0].OUT_cfg\" output=\"divisible_mult_18x18.out\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "            </interconnect>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <mode name=\"mult_18x18\">\n");
	fprintf(fpout, "            <pb_type name=\"mult_18x18_slice\" num_pb=\"1\">\n");
	fprintf(fpout, "              <input name=\"A_cfg\" num_pins=\"18\"/>\n");
	fprintf(fpout, "              <input name=\"B_cfg\" num_pins=\"18\"/>\n");
	fprintf(fpout, "              <output name=\"OUT_cfg\" num_pins=\"36\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "              <pb_type name=\"mult_18x18\" blif_model=\".subckt multiply\" num_pb=\"1\" >\n");
	fprintf(fpout, "                <input name=\"a\" num_pins=\"18\"/>\n");
	fprintf(fpout, "                <input name=\"b\" num_pins=\"18\"/>\n");
	fprintf(fpout, "                <output name=\"out\" num_pins=\"36\"/>\n");
	fprintf(fpout, "                <delay_constant max=\"1.523e-9\" in_port=\"mult_18x18.a\" out_port=\"mult_18x18.out\"/>\n");
	fprintf(fpout, "                <delay_constant max=\"1.523e-9\" in_port=\"mult_18x18.b\" out_port=\"mult_18x18.out\"/>\n");
	fprintf(fpout, "              </pb_type>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "              <interconnect>\n");
	fprintf(fpout, "                <direct name=\"a2a\" input=\"mult_18x18_slice.A_cfg\" output=\"mult_18x18.a\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"b2b\" input=\"mult_18x18_slice.B_cfg\" output=\"mult_18x18.b\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "                <direct name=\"out2out\" input=\"mult_18x18.out\" output=\"mult_18x18_slice.OUT_cfg\">\n");
	fprintf(fpout, "                </direct>\n");
	fprintf(fpout, "              </interconnect>\n");
	fprintf(fpout, "              <power method=\"pin-toggle\">\n");
	fprintf(fpout, "                <port name=\"A_cfg\" energy_per_toggle=\"1.09e-12\"/>\n");
	fprintf(fpout, "                <port name=\"B_cfg\" energy_per_toggle=\"1.09e-12\"/>\n");
	fprintf(fpout, "                <static_power power_per_instance=\"0.0\"/>					\n");
	fprintf(fpout, "              </power>\n");
	fprintf(fpout, "            </pb_type>\n");
	fprintf(fpout, "            <interconnect>\n");
	fprintf(fpout, "              <direct name=\"a2a\" input=\"divisible_mult_18x18.a\" output=\"mult_18x18_slice.A_cfg\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "              <direct name=\"b2b\" input=\"divisible_mult_18x18.b\" output=\"mult_18x18_slice.B_cfg\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "              <direct name=\"out2out\" input=\"mult_18x18_slice.OUT_cfg\" output=\"divisible_mult_18x18.out\">\n");
	fprintf(fpout, "              </direct>\n");
	fprintf(fpout, "            </interconnect>\n");
	fprintf(fpout, "          </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <power method=\"sum-of-children\"/>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier. \n");
	fprintf(fpout, "		   Subtract 72.5 ps delay, which is already in the connection block input mux, leading\n");
	fprintf(fpout, "              -->\n");
	fprintf(fpout, "          <direct name=\"a2a\" input=\"mult_36.a\" output=\"divisible_mult_18x18[1:0].a\">\n");
	fprintf(fpout, "            <delay_constant max=\"134e-12\" in_port=\"mult_36.a\" out_port=\"divisible_mult_18x18[1:0].a\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"b2b\" input=\"mult_36.b\" output=\"divisible_mult_18x18[1:0].b\">\n");
	fprintf(fpout, "            <delay_constant max=\"134e-12\" in_port=\"mult_36.b\" out_port=\"divisible_mult_18x18[1:0].b\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"out2out\" input=\"divisible_mult_18x18[1:0].out\" output=\"mult_36.out\">\n");
	fprintf(fpout, "            <delay_constant max=\"1.09e-9\" in_port=\"divisible_mult_18x18[1:0].out\" out_port=\"mult_36.out\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mult_36x36\">\n");
	fprintf(fpout, "        <pb_type name=\"mult_36x36_slice\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"A_cfg\" num_pins=\"36\"/>\n");
	fprintf(fpout, "          <input name=\"B_cfg\" num_pins=\"36\"/>\n");
	fprintf(fpout, "          <output name=\"OUT_cfg\" num_pins=\"72\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <pb_type name=\"mult_36x36\" blif_model=\".subckt multiply\" num_pb=\"1\">\n");
	fprintf(fpout, "            <input name=\"a\" num_pins=\"36\"/>\n");
	fprintf(fpout, "            <input name=\"b\" num_pins=\"36\"/>\n");
	fprintf(fpout, "            <output name=\"out\" num_pins=\"72\"/>\n");
	fprintf(fpout, "            <delay_constant max=\"1.523e-9\" in_port=\"mult_36x36.a\" out_port=\"mult_36x36.out\"/>\n");
	fprintf(fpout, "            <delay_constant max=\"1.523e-9\" in_port=\"mult_36x36.b\" out_port=\"mult_36x36.out\"/>\n");
	fprintf(fpout, "          </pb_type>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <interconnect>\n");
	fprintf(fpout, "            <direct name=\"a2a\" input=\"mult_36x36_slice.A_cfg\" output=\"mult_36x36.a\">\n");
	fprintf(fpout, "            </direct>\n");
	fprintf(fpout, "            <direct name=\"b2b\" input=\"mult_36x36_slice.B_cfg\" output=\"mult_36x36.b\">\n");
	fprintf(fpout, "            </direct>\n");
	fprintf(fpout, "            <direct name=\"out2out\" input=\"mult_36x36.out\" output=\"mult_36x36_slice.OUT_cfg\">\n");
	fprintf(fpout, "            </direct>\n");
	fprintf(fpout, "          </interconnect>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"A_cfg\" energy_per_toggle=\"2.13e-12\"/>\n");
	fprintf(fpout, "            <port name=\"B_cfg\" energy_per_toggle=\"2.13e-12\"/>\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier. \n");
	fprintf(fpout, "		   Subtract 72.5 ps delay, which is already in the connection block input mux, leading\n");
	fprintf(fpout, "		   to a 134 ps delay.\n");
	fprintf(fpout, "              -->\n");
	fprintf(fpout, "          <direct name=\"a2a\" input=\"mult_36.a\" output=\"mult_36x36_slice.A_cfg\">\n");
	fprintf(fpout, "            <delay_constant max=\"134e-12\" in_port=\"mult_36.a\" out_port=\"mult_36x36_slice.A_cfg\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"b2b\" input=\"mult_36.b\" output=\"mult_36x36_slice.B_cfg\">\n");
	fprintf(fpout, "            <delay_constant max=\"134e-12\" in_port=\"mult_36.b\" out_port=\"mult_36x36_slice.B_cfg\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"out2out\" input=\"mult_36x36_slice.OUT_cfg\" output=\"mult_36.out\">\n");
	fprintf(fpout, "            <delay_constant max=\"1.93e-9\" in_port=\"mult_36x36_slice.OUT_cfg\" out_port=\"mult_36.out\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
	fprintf(fpout, "      <pinlocations pattern=\"spread\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <!-- Place this multiplier block every 8 columns from (and including) the sixth column -->\n");
	fprintf(fpout, "      <gridlocations>\n");
	fprintf(fpout, "        <loc type=\"col\" start=\"6\" repeat=\"8\" priority=\"2\"/>\n");
	fprintf(fpout, "      </gridlocations>		  \n");
	fprintf(fpout, "      <power method=\"sum-of-children\"/>\n");
	fprintf(fpout, "    </pb_type>\n");
	fprintf(fpout, "    <!-- Define fracturable multiplier end -->\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "    <!-- Define fracturable memory begin -->\n");
	fprintf(fpout, "    <!-- 32 Kb Memory that can operate from 512x64 to 32Kx1 for single-port mode and 1024x32 to 32Kx1 for dual-port mode.  \n");
	fprintf(fpout, "           Area and delay based off Stratix IV 9K and 144K memories (delay from linear interpolation, Tsu(483 ps, 636 ps) Tco(1084ps, 1969ps)).  \n");
	fprintf(fpout, "           Input delay = 204ps (from Stratix IV LAB line) - 72ps (this architecture does not lump connection box delay in internal delay)\n");
	fprintf(fpout, "           Output delay = M4K buffer 50ps\n");
	fprintf(fpout, "      -->\n");
	fprintf(fpout, "    <pb_type name=\"memory\" height=\"6\">\n");
	fprintf(fpout, "      <input name=\"addr1\" num_pins=\"15\"/>\n");
	fprintf(fpout, "      <input name=\"addr2\" num_pins=\"15\"/>\n");
	fprintf(fpout, "      <input name=\"data\" num_pins=\"64\"/>\n");
	fprintf(fpout, "      <input name=\"we1\" num_pins=\"1\"/>\n");
	fprintf(fpout, "      <input name=\"we2\" num_pins=\"1\"/>\n");
	fprintf(fpout, "      <output name=\"out\" num_pins=\"64\"/>\n");
	fprintf(fpout, "      <clock name=\"clk\" num_pins=\"1\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <!-- Specify single port mode first -->\n");
	fprintf(fpout, "      <mode name=\"mem_512x64_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_512x64_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"9\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"64\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"64\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_512x64_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_512x64_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_512x64_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_512x64_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[8:0]\" output=\"mem_512x64_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[8:0]\" out_port=\"mem_512x64_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[63:0]\" output=\"mem_512x64_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[63:0]\" out_port=\"mem_512x64_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_512x64_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_512x64_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_512x64_sp.out\" output=\"memory.out[63:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_512x64_sp.out\" out_port=\"memory.out[63:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_512x64_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_1024x32_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_1024x32_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"10\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"32\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"32\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[9:0]\" output=\"mem_1024x32_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[9:0]\" out_port=\"mem_1024x32_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[31:0]\" output=\"mem_1024x32_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[31:0]\" out_port=\"mem_1024x32_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_1024x32_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_1024x32_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_1024x32_sp.out\" output=\"memory.out[31:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_sp.out\" out_port=\"memory.out[31:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_1024x32_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");

	fprintf(fpout, "      <mode name=\"mem_2048x16_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_2048x16_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"11\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"16\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"16\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[10:0]\" output=\"mem_2048x16_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[10:0]\" out_port=\"mem_2048x16_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[15:0]\" output=\"mem_2048x16_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[15:0]\" out_port=\"mem_2048x16_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x16_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x16_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_2048x16_sp.out\" output=\"memory.out[15:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_sp.out\" out_port=\"memory.out[15:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x16_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_4096x8_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_4096x8_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"12\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"8\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"8\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_4096x8_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[11:0]\" output=\"mem_4096x8_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[11:0]\" out_port=\"mem_4096x8_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[7:0]\" output=\"mem_4096x8_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[7:0]\" out_port=\"mem_4096x8_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_4096x8_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_4096x8_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_4096x8_sp.out\" output=\"memory.out[7:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_4096x8_sp.out\" out_port=\"memory.out[7:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_4096x8_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_8192x4_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_8192x4_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"13\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"4\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"4\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[12:0]\" output=\"mem_8192x4_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[12:0]\" out_port=\"mem_8192x4_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[3:0]\" output=\"mem_8192x4_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[3:0]\" out_port=\"mem_8192x4_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_8192x4_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_8192x4_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_8192x4_sp.out\" output=\"memory.out[3:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_sp.out\" out_port=\"memory.out[3:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_8192x4_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_16384x2_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_16384x2_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"14\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"2\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"2\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[13:0]\" output=\"mem_16384x2_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[13:0]\" out_port=\"mem_16384x2_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[1:0]\" output=\"mem_16384x2_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[1:0]\" out_port=\"mem_16384x2_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_16384x2_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_16384x2_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_16384x2_sp.out\" output=\"memory.out[1:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_sp.out\" out_port=\"memory.out[1:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_16384x2_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>  \n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_32768x1_sp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_32768x1_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr\" num_pins=\"15\" port_class=\"address\"/>\n");
	fprintf(fpout, "          <input name=\"data\" num_pins=\"1\" port_class=\"data_in\"/>\n");
	fprintf(fpout, "          <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
	fprintf(fpout, "          <output name=\"out\" num_pins=\"1\" port_class=\"data_out\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.addr\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.data\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.we\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_sp.out\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[14:0]\" output=\"mem_32768x1_sp.addr\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[14:0]\" out_port=\"mem_32768x1_sp.addr\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[0:0]\" output=\"mem_32768x1_sp.data\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[0:0]\" out_port=\"mem_32768x1_sp.data\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_32768x1_sp.we\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_32768x1_sp.we\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_32768x1_sp.out\" output=\"memory.out[0:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_sp.out\" out_port=\"memory.out[0:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_32768x1_sp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode> \n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <!-- Specify true dual port mode next -->\n");
	fprintf(fpout, "      <mode name=\"mem_1024x32_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_1024x32_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"10\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"10\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"32\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"32\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"32\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"32\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[9:0]\" output=\"mem_1024x32_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[9:0]\" out_port=\"mem_1024x32_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[9:0]\" output=\"mem_1024x32_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[9:0]\" out_port=\"mem_1024x32_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[31:0]\" output=\"mem_1024x32_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[31:0]\" out_port=\"mem_1024x32_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[63:32]\" output=\"mem_1024x32_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[63:32]\" out_port=\"mem_1024x32_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_1024x32_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_1024x32_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_1024x32_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_1024x32_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_1024x32_dp.out1\" output=\"memory.out[31:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_dp.out1\" out_port=\"memory.out[31:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_1024x32_dp.out2\" output=\"memory.out[63:32]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_dp.out2\" out_port=\"memory.out[63:32]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_1024x32_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_2048x16_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_2048x16_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"11\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"11\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"16\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"16\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"16\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"16\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[10:0]\" output=\"mem_2048x16_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[10:0]\" out_port=\"mem_2048x16_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[10:0]\" output=\"mem_2048x16_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[10:0]\" out_port=\"mem_2048x16_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[15:0]\" output=\"mem_2048x16_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[15:0]\" out_port=\"mem_2048x16_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[31:16]\" output=\"mem_2048x16_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[31:16]\" out_port=\"mem_2048x16_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x16_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x16_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_2048x16_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_2048x16_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_2048x16_dp.out1\" output=\"memory.out[15:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_dp.out1\" out_port=\"memory.out[15:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_2048x16_dp.out2\" output=\"memory.out[31:16]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_dp.out2\" out_port=\"memory.out[31:16]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x16_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_2048x8_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_2048x8_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"12\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"12\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"8\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"8\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"8\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"8\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x8_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x8_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[11:0]\" output=\"mem_2048x8_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[11:0]\" out_port=\"mem_2048x8_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[11:0]\" output=\"mem_2048x8_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[11:0]\" out_port=\"mem_2048x8_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[7:0]\" output=\"mem_2048x8_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[7:0]\" out_port=\"mem_2048x8_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[15:8]\" output=\"mem_2048x8_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[15:8]\" out_port=\"mem_2048x8_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x8_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x8_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_2048x8_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_2048x8_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_2048x8_dp.out1\" output=\"memory.out[7:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_2048x8_dp.out1\" out_port=\"memory.out[7:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_2048x8_dp.out2\" output=\"memory.out[15:8]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_2048x8_dp.out2\" out_port=\"memory.out[15:8]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x8_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "      <mode name=\"mem_8192x4_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_8192x4_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"13\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"13\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"4\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"4\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"4\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"4\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[12:0]\" output=\"mem_8192x4_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[12:0]\" out_port=\"mem_8192x4_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[12:0]\" output=\"mem_8192x4_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[12:0]\" out_port=\"mem_8192x4_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[3:0]\" output=\"mem_8192x4_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[3:0]\" out_port=\"mem_8192x4_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[7:4]\" output=\"mem_8192x4_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[7:4]\" out_port=\"mem_8192x4_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_8192x4_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_8192x4_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_8192x4_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_8192x4_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_8192x4_dp.out1\" output=\"memory.out[3:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_dp.out1\" out_port=\"memory.out[3:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_8192x4_dp.out2\" output=\"memory.out[7:4]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_dp.out2\" out_port=\"memory.out[7:4]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_8192x4_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "      <mode name=\"mem_16384x2_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_16384x2_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"14\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"14\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"2\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"2\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"2\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"2\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[13:0]\" output=\"mem_16384x2_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[13:0]\" out_port=\"mem_16384x2_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[13:0]\" output=\"mem_16384x2_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[13:0]\" out_port=\"mem_16384x2_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[1:0]\" output=\"mem_16384x2_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[1:0]\" out_port=\"mem_16384x2_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[3:2]\" output=\"mem_16384x2_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[3:2]\" out_port=\"mem_16384x2_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_16384x2_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_16384x2_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_16384x2_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_16384x2_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_16384x2_dp.out1\" output=\"memory.out[1:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_dp.out1\" out_port=\"memory.out[1:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_16384x2_dp.out2\" output=\"memory.out[3:2]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_dp.out2\" out_port=\"memory.out[3:2]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_16384x2_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <mode name=\"mem_32768x1_dp\">\n");
	fprintf(fpout, "        <pb_type name=\"mem_32768x1_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
	fprintf(fpout, "          <input name=\"addr1\" num_pins=\"15\" port_class=\"address1\"/>\n");
	fprintf(fpout, "          <input name=\"addr2\" num_pins=\"15\" port_class=\"address2\"/>\n");
	fprintf(fpout, "          <input name=\"data1\" num_pins=\"1\" port_class=\"data_in1\"/>\n");
	fprintf(fpout, "          <input name=\"data2\" num_pins=\"1\" port_class=\"data_in2\"/>\n");
	fprintf(fpout, "          <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
	fprintf(fpout, "          <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
	fprintf(fpout, "          <output name=\"out1\" num_pins=\"1\" port_class=\"data_out1\"/>\n");
	fprintf(fpout, "          <output name=\"out2\" num_pins=\"1\" port_class=\"data_out2\"/>\n");
	fprintf(fpout, "          <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.addr1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.data1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.we1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.addr2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.data2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.we2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_dp.out1\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_dp.out2\" clock=\"clk\"/>\n");
	fprintf(fpout, "          <power method=\"pin-toggle\">\n");
	fprintf(fpout, "            <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/>					\n");
	fprintf(fpout, "            <static_power power_per_instance=\"0.0\"/>\n");
	fprintf(fpout, "          </power>\n");
	fprintf(fpout, "        </pb_type>\n");
	fprintf(fpout, "        <interconnect>\n");
	fprintf(fpout, "          <direct name=\"address1\" input=\"memory.addr1[14:0]\" output=\"mem_32768x1_dp.addr1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr1[14:0]\" out_port=\"mem_32768x1_dp.addr1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"address2\" input=\"memory.addr2[14:0]\" output=\"mem_32768x1_dp.addr2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.addr2[14:0]\" out_port=\"mem_32768x1_dp.addr2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data1\" input=\"memory.data[0:0]\" output=\"mem_32768x1_dp.data1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[0:0]\" out_port=\"mem_32768x1_dp.data1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"data2\" input=\"memory.data[1:1]\" output=\"mem_32768x1_dp.data2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.data[1:1]\" out_port=\"mem_32768x1_dp.data2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_32768x1_dp.we1\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_32768x1_dp.we1\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_32768x1_dp.we2\">\n");
	fprintf(fpout, "            <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_32768x1_dp.we2\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout1\" input=\"mem_32768x1_dp.out1\" output=\"memory.out[0:0]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_dp.out1\" out_port=\"memory.out[0:0]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"dataout2\" input=\"mem_32768x1_dp.out2\" output=\"memory.out[1:1]\">\n");
	fprintf(fpout, "            <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_dp.out2\" out_port=\"memory.out[1:1]\"/>\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "          <direct name=\"clk\" input=\"memory.clk\" output=\"mem_32768x1_dp.clk\">\n");
	fprintf(fpout, "          </direct>\n");
	fprintf(fpout, "        </interconnect>\n");
	fprintf(fpout, "      </mode>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <!-- Every input pin is driven by 15%% of the tracks in a channel, every output pin is driven by 10%% of the tracks in a channel -->\n");
	fprintf(fpout, "      <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
	fprintf(fpout, "      <pinlocations pattern=\"spread\"/>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <!-- Place this memory block every 8 columns from (and including) the second column -->\n");
	fprintf(fpout, "      <gridlocations>\n");
	fprintf(fpout, "        <loc type=\"col\" start=\"2\" repeat=\"8\" priority=\"2\"/>\n");
	fprintf(fpout, "      </gridlocations>\n");
	fprintf(fpout, "\n");
	fprintf(fpout, "      <power method=\"sum-of-children\"/>\n");
	fprintf(fpout, "    </pb_type>\n");
	fprintf(fpout, "    <!-- Define fracturable memory end -->\n");
	fprintf(fpout, "\n");

	fprintf(fpout, "  </complexblocklist>\n");
	fprintf(fpout, "  <power>\n");
	fprintf(fpout, "    <local_interconnect C_wire=\"2.5e-10\"/>\n");
	fprintf(fpout, "  </power>\n");
	fprintf(fpout, "  <clocks>\n");
	fprintf(fpout, "    <clock buffer_size=\"auto\" C_wire=\"2.5e-10\"/>\n");
	fprintf(fpout, "  </clocks>\n");
	fprintf(fpout, "</architecture>\n");
}

